using LiJ.Common.Core;
using LiJ.Common.Encrypt;
using LiJ.Common.Extention;
using LiJ.Common.Plugs.CachePlug;
using LiJ.Http.Mos;
using LiJ.Framework.Official.Assist.Mos;
using LiJ.Framework.Official.SysTools.Mos;
using System;
using System.Text;
using System.Threading.Tasks;

namespace LiJ.Framework.Official.Assist
{
	/// <summary>
	///   微信公众号辅助接口
	/// </summary>
	public class WxOffAssistApi : WxOffBaseApi
	{
		private static readonly Random _rnd = new Random();

		private static readonly char[] _arrChar = new char[60]
		{
			'0',
			'1',
			'2',
			'3',
			'4',
			'5',
			'6',
			'7',
			'8',
			'9',
			'a',
			'b',
			'd',
			'c',
			'e',
			'f',
			'g',
			'h',
			'i',
			'j',
			'k',
			'l',
			'm',
			'n',
			'p',
			'r',
			'q',
			's',
			't',
			'u',
			'v',
			'w',
			'z',
			'y',
			'x',
			'A',
			'B',
			'C',
			'D',
			'E',
			'F',
			'G',
			'H',
			'I',
			'J',
			'K',
			'L',
			'M',
			'N',
			'Q',
			'P',
			'R',
			'T',
			'S',
			'V',
			'U',
			'W',
			'X',
			'Y',
			'Z'
		};

		/// <summary>
		///   辅助类Api
		/// </summary>
		/// <param name="config">配置信息，如果这里不传，需要在程序入口静态 WxBaseApi.DefaultConfig 属性赋值</param>
		public WxOffAssistApi(AppConfig config = null)
			: base(config)
		{
		}

		/// <summary>
		///  获取js 接口 Ticket
		/// 内部已经处理缓存
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		public async Task<WxGetJsTicketResp> GetJsTicketFromCacheAsync(WxJsTicketType type)
		{
			string key = string.Format("social_wx_offcial_jsticket_{0}_{1}", base.ApiConfig.AppId, type);
			WxGetJsTicketResp wxGetJsTicketResp = CacheUtil.Get<WxGetJsTicketResp>(key, base.ModuleName);
			if (wxGetJsTicketResp != null && wxGetJsTicketResp.expires_time > DateTime.Now)
			{
				return wxGetJsTicketResp;
			}
			WxGetJsTicketResp wxGetJsTicketResp2 = await this.GetJsTicketFromWxAsync(type);
			if (!wxGetJsTicketResp2.IsSuccess())
			{
				return wxGetJsTicketResp2;
			}
			wxGetJsTicketResp2.expires_time = DateTime.Now.AddSeconds((double)wxGetJsTicketResp2.expires_in);
			CacheUtil.AddOrUpdate(key, wxGetJsTicketResp2, TimeSpan.FromSeconds((double)(wxGetJsTicketResp2.expires_in - 10)), null, base.ModuleName);
			return wxGetJsTicketResp2;
		}

		/// <summary>
		///  获取js 接口 Ticket
		/// 内部已经处理缓存
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		public async Task<WxGetJsTicketResp> GetJsTicketFromWxAsync(WxJsTicketType type)
		{
			LHttpRequest req = new LHttpRequest
			{
				HttpMothed = HttpMothed.Get,
				AddressUrl = "https://api.weixin.qq.com" + "/cgi-bin/ticket/getticket?type=" + type.ToString()
			};
			return await base.RestCommonOffcialAsync<WxGetJsTicketResp>(req, null);
		}

		/// <summary>
		///  获取jssdk签名信息
		/// </summary>
		/// <param name="url"></param>
		/// <returns></returns>
		public async Task<WxJsSdkSignatureResp> GetJsSdkSignature(string url)
		{
			WxGetJsTicketResp wxGetJsTicketResp = await this.GetJsTicketFromCacheAsync(WxJsTicketType.jsapi);
			if (!wxGetJsTicketResp.IsSuccess())
			{
				return ((ResultMo)wxGetJsTicketResp).ConvertToResult<WxJsSdkSignatureResp>();
			}
			WxJsSdkSignatureResp wxJsSdkSignatureResp = new WxJsSdkSignatureResp
			{
				app_id = base.ApiConfig.AppId,
				noncestr = WxOffAssistApi.GenerateNonceStr(),
				timestamp = DateTime.Now.ToLocalSeconds()
			};
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("jsapi_ticket=").Append(wxGetJsTicketResp.ticket);
			stringBuilder.Append("&noncestr=").Append(wxJsSdkSignatureResp.noncestr);
			stringBuilder.Append("&timestamp=").Append(wxJsSdkSignatureResp.timestamp);
			if (!string.IsNullOrEmpty(url))
			{
				stringBuilder.Append("&url=").Append(url);
			}
			wxJsSdkSignatureResp.signature = Sha1.Encrypt(stringBuilder.ToString(), null);
			return wxJsSdkSignatureResp;
		}

		/// <summary>
		/// 生成随机串
		/// </summary>
		/// <returns></returns>
		private static string GenerateNonceStr()
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < 8; i++)
			{
				stringBuilder.Append(WxOffAssistApi._arrChar[WxOffAssistApi._rnd.Next(0, 59)].ToString());
			}
			return stringBuilder.ToString();
		}
	}
}
